Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / frontend / components / messages / ConversationDropDownMenu.vue

Displaying Raw • Download


meshchatx/src/frontend/components/messages/ConversationDropDownMenu.vue 7d7cd7d48701e74ab38cef0db1eca1b0cd23cf87 (7d7cd7d4) Text, 7.51 KB

Tb4b4b4<Tff7b72templateTb4b4b4>
Tb4b4b4<Tff7b72DropDownMenuTb4b4b4>
Tb4b4b4<Tff7b72template #Te6edf3buttonTb4b4b4>
Tb4b4b4<Tff7b72IconButtonTb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"dots-vertical" Te6edf3classTff7b72=Ta5d6ff"size-6" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72IconButtonTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72templateTb4b4b4>
Tb4b4b4<Tff7b72template #Te6edf3itemsTb4b4b4>
T8b949e<!-- popout button -->
Tb4b4b4<Tff7b72DropDownMenuItem Tb4b4b4@Te6edf3clickTff7b72=Ta5d6ff"Te6edf3$emitTb4b4b4(Ta5d6ff'popout'Tb4b4b4)Ta5d6ff"Tb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"open-in-new" Te6edf3classTff7b72=Ta5d6ff"size-5" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>Popout ChatTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuItemTb4b4b4>

T8b949e<!-- ping button -->
Tb4b4b4<Tff7b72DropDownMenuItem Tb4b4b4@Te6edf3clickTff7b72=Ta5d6ff"Te6edf3onPingDestinationTa5d6ff"Tb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"flash" Te6edf3classTff7b72=Ta5d6ff"size-5" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>Ping DestinationTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuItemTb4b4b4>

T8b949e<!-- set custom display name button -->
Tb4b4b4<Tff7b72DropDownMenuItem Tb4b4b4@Te6edf3clickTff7b72=Ta5d6ff"Te6edf3onSetCustomDisplayNameTa5d6ff"Tb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"account-edit" Te6edf3classTff7b72=Ta5d6ff"size-5" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>Set Custom Display NameTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuItemTb4b4b4>

T8b949e<!-- block/unblock button -->
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"border-t"Tb4b4b4>
Tb4b4b4<Tff7b72DropDownMenuItem Te6edf3v-ifTff7b72=Ta5d6ff"Tff7b72!Te6edf3isBlockedTa5d6ff" Tb4b4b4@Te6edf3clickTff7b72=Ta5d6ff"Te6edf3onBlockDestinationTa5d6ff"Tb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"block-helper" Te6edf3classTff7b72=Ta5d6ff"size-5 text-red-500" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"text-red-500"Tb4b4b4>Banish UserTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuItemTb4b4b4>
Tb4b4b4<Tff7b72DropDownMenuItem Te6edf3v-else Tb4b4b4@Te6edf3clickTff7b72=Ta5d6ff"Te6edf3onUnblockDestinationTa5d6ff"Tb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"check-circle" Te6edf3classTff7b72=Ta5d6ff"size-5 text-green-500" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"text-green-500"Tb4b4b4>Lift BanishmentTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuItemTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>

T8b949e<!-- delete message history button -->
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"border-t"Tb4b4b4>
Tb4b4b4<Tff7b72DropDownMenuItem Tb4b4b4@Te6edf3clickTff7b72=Ta5d6ff"Te6edf3onDeleteMessageHistoryTa5d6ff"Tb4b4b4>
Tb4b4b4<Tff7b72MaterialDesignIcon Te6edf3icon-nameTff7b72=Ta5d6ff"delete" Te6edf3classTff7b72=Ta5d6ff"size-5 text-red-500" Tb4b4b4/Tb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"text-red-500"Tb4b4b4>Delete Message HistoryTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuItemTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72templateTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72DropDownMenuTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72templateTb4b4b4>

Tb4b4b4<Tff7b72scriptTb4b4b4>
Tff7b72import Te6edf3DropDownMenu Tff7b72from Ta5d6ff"../DropDownMenu.vue"Tb4b4b4;
Tff7b72import Te6edf3DropDownMenuItem Tff7b72from Ta5d6ff"../DropDownMenuItem.vue"Tb4b4b4;
Tff7b72import Te6edf3IconButton Tff7b72from Ta5d6ff"../IconButton.vue"Tb4b4b4;
Tff7b72import Te6edf3MaterialDesignIcon Tff7b72from Ta5d6ff"../MaterialDesignIcon.vue"Tb4b4b4;
Tff7b72import Te6edf3DialogUtils Tff7b72from Ta5d6ff"../../js/DialogUtils"Tb4b4b4;
Tff7b72import Te6edf3GlobalState Tff7b72from Ta5d6ff"../../js/GlobalState"Tb4b4b4;
Tff7b72import Te6edf3GlobalEmitter Tff7b72from Ta5d6ff"../../js/GlobalEmitter"Tb4b4b4;

Tff7b72export Tff7b72default Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"ConversationDropDownMenu"Tb4b4b4,
Te6edf3componentsTff7b72: Tb4b4b4{
Te6edf3IconButtonTb4b4b4,
Te6edf3DropDownMenuItemTb4b4b4,
Te6edf3DropDownMenuTb4b4b4,
Te6edf3MaterialDesignIconTb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3propsTff7b72: Tb4b4b4{
Te6edf3peerTff7b72: Tb4b4b4{
Te6edf3typeTff7b72: Tffa657ObjectTb4b4b4,
Te6edf3requiredTff7b72: Tff7b72trueTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3emitsTff7b72: Tb4b4b4[Ta5d6ff"conversation-deleted"Tb4b4b4, Ta5d6ff"set-custom-display-name"Tb4b4b4, Ta5d6ff"block-status-changed"Tb4b4b4, Ta5d6ff"popout"Tb4b4b4]Tb4b4b4,
Te6edf3computedTff7b72: Tb4b4b4{
Te6edf3isBlockedTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3GlobalStateTb4b4b4.Te6edf3blockedDestinationsTb4b4b4.Te6edf3someTb4b4b4(Tb4b4b4(Te6edf3bTb4b4b4) Tb4b4b4=> Te6edf3bTb4b4b4.Te6edf3destination_hash Tff7b72=== Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4.Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3methodsTff7b72: Tb4b4b4{
Tff7b72async Te6edf3onBlockDestinationTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(
Tff7b72!Tb4b4b4(Tff7b72await Te6edf3DialogUtilsTb4b4b4.Te6edf3confirmTb4b4b4(
Ta5d6ff"Are you sure you want to banish this user? They will not be able to send you messages or establish links."
Tb4b4b4)Tb4b4b4)
Tb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}

Tff7b72try Tb4b4b4{
Tff7b72await Tffa657windowTb4b4b4.Te6edf3axiosTb4b4b4.Te6edf3postTb4b4b4(Ta5d6ff"/api/v1/blocked-destinations"Tb4b4b4, Tb4b4b4{
Te6edf3destination_hashTff7b72: Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4.Te6edf3destination_hashTb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3GlobalEmitterTb4b4b4.Te6edf3emitTb4b4b4(Ta5d6ff"block-status-changed"Tb4b4b4)Tb4b4b4;
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.user_banished"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3$emitTb4b4b4(Ta5d6ff"block-status-changed"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.failed_banish_user"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tff7b72async Te6edf3onUnblockDestinationTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72await Tffa657windowTb4b4b4.Te6edf3axiosTb4b4b4.Tff7b72deleteTb4b4b4(Ta5d6ff`Ta5d6ff/api/v1/blocked-destinations/Tffd700${Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4.Te6edf3destination_hashTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3GlobalEmitterTb4b4b4.Te6edf3emitTb4b4b4(Ta5d6ff"block-status-changed"Tb4b4b4)Tb4b4b4;
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"banishment.banishment_lifted"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3$emitTb4b4b4(Ta5d6ff"block-status-changed"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"banishment.failed_lift_banishment"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tff7b72async Te6edf3onDeleteMessageHistoryTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// ask user to confirm deleting conversation history
Tff7b72if Tb4b4b4(Tff7b72!Tb4b4b4(Tff7b72await Te6edf3DialogUtilsTb4b4b4.Te6edf3confirmTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.delete_history_confirm"Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}

T8b949e// delete all lxmf messages from "us to destination" and from "destination to us"
Tff7b72try Tb4b4b4{
Tff7b72await Tffa657windowTb4b4b4.Te6edf3axiosTb4b4b4.Tff7b72deleteTb4b4b4(Ta5d6ff`Ta5d6ff/api/v1/lxmf-messages/conversation/Tffd700${Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4.Te6edf3destination_hashTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.failed_delete_history"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e// fire callback
Tff7b72thisTb4b4b4.Te6edf3$emitTb4b4b4(Ta5d6ff"conversation-deleted"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4,
Tff7b72async Te6edf3onSetCustomDisplayNameTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3$emitTb4b4b4(Ta5d6ff"set-custom-display-name"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4,
Tff7b72async Te6edf3onPingDestinationTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Tff7b72thisTb4b4b4.Te6edf3peer Tff7b72|| Tff7b72!Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4.Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.invalid_destination_hash"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3destinationHash Tff7b72= Tff7b72thisTb4b4b4.Te6edf3peerTb4b4b4.Te6edf3destination_hashTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationHashTb4b4b4.Te6edf3length Tff7b72!== T79c0ff32 Tff7b72|| Tff7b72!Ta5d6ff/^[0-9a-fA-F]+$/Tb4b4b4.Te6edf3testTb4b4b4(Te6edf3destinationHashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.invalid_destination_hash_format"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}

Tff7b72try Tb4b4b4{
T8b949e// ping destination
Tff7b72const Te6edf3response Tff7b72= Tff7b72await Tffa657windowTb4b4b4.Te6edf3axiosTb4b4b4.Te6edf3getTb4b4b4(Ta5d6ff`Ta5d6ff/api/v1/ping/Tffd700${Te6edf3destinationHashTffd700}Ta5d6ff/lxmf.deliveryTa5d6ff`Tb4b4b4, Tb4b4b4{
Te6edf3paramsTff7b72: Tb4b4b4{
Te6edf3timeoutTff7b72: T79c0ff30Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Tff7b72const Te6edf3pingResult Tff7b72= Te6edf3responseTb4b4b4.Te6edf3dataTb4b4b4.Te6edf3ping_resultTb4b4b4;
Tff7b72const Te6edf3rttMilliseconds Tff7b72= Tb4b4b4(Te6edf3pingResultTb4b4b4.Te6edf3rtt Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4.Te6edf3toFixedTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3rttDurationString Tff7b72= Ta5d6ff`Tffd700${Te6edf3rttMillisecondsTffd700}Ta5d6ff msTa5d6ff`Tb4b4b4;

Tff7b72const Te6edf3info Tff7b72= Tb4b4b4[
Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.ping_reply_from"Tb4b4b4, Tb4b4b4{ Te6edf3hashTff7b72: Te6edf3destinationHash Tb4b4b4}Tb4b4b4)Tb4b4b4,
Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.duration"Tb4b4b4, Tb4b4b4{ Te6edf3durationTff7b72: Te6edf3rttDurationString Tb4b4b4}Tb4b4b4)Tb4b4b4,
Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.hops_there"Tb4b4b4, Tb4b4b4{ Te6edf3countTff7b72: Te6edf3pingResultTb4b4b4.Te6edf3hops_there Tb4b4b4}Tb4b4b4)Tb4b4b4,
Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.hops_back"Tb4b4b4, Tb4b4b4{ Te6edf3countTff7b72: Te6edf3pingResultTb4b4b4.Te6edf3hops_back Tb4b4b4}Tb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4;

T8b949e// add signal quality if available
Tff7b72if Tb4b4b4(Te6edf3pingResultTb4b4b4.Te6edf3quality Tff7b72!= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3infoTb4b4b4.Te6edf3pushTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.signal_quality"Tb4b4b4, Tb4b4b4{ Te6edf3qualityTff7b72: Te6edf3pingResultTb4b4b4.Te6edf3quality Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e// add rssi if available
Tff7b72if Tb4b4b4(Te6edf3pingResultTb4b4b4.Te6edf3rssi Tff7b72!= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3infoTb4b4b4.Te6edf3pushTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.rssi_val"Tb4b4b4, Tb4b4b4{ Te6edf3rssiTff7b72: Te6edf3pingResultTb4b4b4.Te6edf3rssi Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e// add snr if available
Tff7b72if Tb4b4b4(Te6edf3pingResultTb4b4b4.Te6edf3snr Tff7b72!= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3infoTb4b4b4.Te6edf3pushTb4b4b4(Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.snr_val"Tb4b4b4, Tb4b4b4{ Te6edf3snrTff7b72: Te6edf3pingResultTb4b4b4.Te6edf3snr Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e// show result
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Te6edf3infoTb4b4b4.Te6edf3joinTb4b4b4(Ta5d6ff"\n"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3message Tff7b72= Te6edf3eTb4b4b4.Te6edf3responseTff7b72?Tb4b4b4.Te6edf3dataTff7b72?Tb4b4b4.Te6edf3message Tff7b72?? Tff7b72thisTb4b4b4.Te6edf3$tTb4b4b4(Ta5d6ff"messages.ping_failed"Tb4b4b4)Tb4b4b4;
Te6edf3DialogUtilsTb4b4b4.Te6edf3alertTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tb4b4b4<Tb4b4b4/Tff7b72scriptTb4b4b4>


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────